package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.constant.RedisConstant;
import com.atguigu.lease.common.contest.LoginUser;
import com.atguigu.lease.common.contest.LoginUserContest;
import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.common.utils.JwtUtil;
import com.atguigu.lease.model.entity.SystemUser;
import com.atguigu.lease.model.entity.UserInfo;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.admin.mapper.SystemUserMapper;
import com.atguigu.lease.web.admin.service.LoginService;
import com.atguigu.lease.web.admin.service.SystemUserService;
import com.atguigu.lease.web.admin.vo.login.CaptchaVo;
import com.atguigu.lease.web.admin.vo.login.LoginVo;
import com.atguigu.lease.web.admin.vo.system.user.SystemUserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import io.jsonwebtoken.Claims;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SystemUserMapper systemUserMapper;
    @ResponseBody
    @RequestMapping("/captcha")
    @Override
    public CaptchaVo getCaptcha() {
        //new对象
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);


        specCaptcha.setCharType(Captcha.TYPE_DEFAULT);
        //文本
        String verCode = specCaptcha.text().toLowerCase();
        //图片(1.图片样式2.图片内容)
        String image = specCaptcha.toBase64();
        //在redis保存key  因为会过期
        String key = RedisConstant.ADMIN_LOGIN_PREFIX + UUID.randomUUID().toString();


        // 存入redis并设置过期时间为1分钟
        redisTemplate.opsForValue().set(key, verCode, RedisConstant.APP_LOGIN_CODE_RESEND_TIME_SEC, TimeUnit.SECONDS);


        //new   captchaVo把图片和key传进去
        return new CaptchaVo(image, key);

    }


    // 登录方法实现
    // 仅用于查询数据库用户记录 并将用户信息封装成一个token 返回给前端
    @Override
    public String login(LoginVo loginVo) {
        // 1. 把传入参数先列举出来
        String username = loginVo.getUsername();
        String password = loginVo.getPassword();
        String captchaKey = loginVo.getCaptchaKey();
        String captchaCode = loginVo.getCaptchaCode();


        // 2. 做逻辑判断
        // 2.1 先判断 账户 密码 验证码 是否为空

        // 2.2 验证码判断
        // 2.2.1 验证码是否过期(键是否存在) 验证码是否正确(值的比较)

        // 2.3 数据库里面有没有这个用户 用户是否存在
        // 用户是否被禁用
        // 用户密码对不对 密码是否正确

        // 全部过 那就可以正常登录 我也可以给你正常返回token


        // 1. 判断账户名是否为空
        if (!StringUtils.hasText(username)) {
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);
        }
        // 2. 判断密码是否为空
        if (!StringUtils.hasText(password)) {
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);
        }
        // 3. 判断验证码是否为空
        if (!StringUtils.hasText(captchaCode)) {
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_NOT_FOUND);
        }
        // 获取code
        String code = redisTemplate.opsForValue().get(captchaKey);
        // 4. 判断验证码是否过期
        // 验证码过期
        if(code == null){
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_EXPIRED);
        }
        // 5.判断验证码是否正确
        if(!code.equals(captchaCode)){
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_ERROR);
        }
        // 这里做了数据库查询操作 所以可以通过返回的这个对象拿到对应的id
        SystemUser systemUser = systemUserMapper.selectOne(new LambdaQueryWrapper<SystemUser>().eq(SystemUser::getUsername, username));
       // 6. 判断数据库有没有这个用户对象 这条记录
        if(systemUser == null){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);
        }
        // 7. 判断是否禁用
        if(systemUser.getStatus() == BaseStatus.DISABLE){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);
        }
        System.out.println(DigestUtils.md5Hex(password));
        // 8. 判断账户密码是否正确
        if(!systemUser.getPassword().equals(DigestUtils.md5Hex(password))){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);
        }


        //创建并返回token
        return JwtUtil.createToken(systemUser.getId(), systemUser.getName());
    }

    @Override
    public SystemUserInfoVo info(Long token) {
        // 1. 做token解析操作 把token里面的userId跟username提取出来
        //得到body
//        Claims claims = JwtUtil.parseToken(token);
        /*{
              "sub": "USER_INFO",
              "exp": 1735209725,
              "userId": 1,
              "username": "admin"
        }*/
        //键值对提取方法
//        Long userId = claims.get("userId", Long.class);
//        String username = claims.get("username", String.class);


        // 2. 把提取出来的userId 传入sql 进行数据库的单条记录查询操作
        SystemUser systemUser = systemUserMapper.selectById(token);


        // 3. 把数据库查询出来的记录(SystemUser对象) 转换成 SystemUserInfoVo

        // 3.1 创建一个 SystemUserInfoVo,然后对vo进行赋值操作
        SystemUserInfoVo systemUserInfoVo = new SystemUserInfoVo();
        systemUserInfoVo.setName(systemUser.getName());
        systemUserInfoVo.setAvatarUrl(systemUser.getAvatarUrl());


        // 3.2 返回vo这个 自定义实体类
        return systemUserInfoVo;
    }
}
